package com.yb.guigu.pick.security.provider;

import com.yb.guigu.pick.cache.manager.api.GuiguPickStringCacheManager;
import com.yb.guigu.pick.core.constant.RedisKeyConstant;
import com.yb.guigu.pick.security.bean.GuiguEmailCodeAuthenticationToken;
import com.yb.guigu.pick.security.bean.GuiguMobileCodeAuthenticationToken;
import com.yb.guigu.pick.security.bean.GuiguPickUser;
import com.yb.guigu.pick.security.bean.GuiguUsernamePasswordAuthenticationToken;
import com.yb.guigu.pick.security.encoder.GuiguPasswordEncoder;
import com.yb.guigu.pick.security.service.IGuiguPickUserDetailsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

/**
 * Copyright (C), 2022-2023, 姚兵
 * Author: 32210
 * Date: 2023/5/31 14:18
 * FileName: GuiguPickUserPasswordAuthenticationProvider
 * Description:
 */
@Component
@Slf4j
public class GuiguPickMobileCodeAuthenticationProvider implements AuthenticationProvider {

    @Autowired
    GuiguPickStringCacheManager guiguPickStringCacheManager;

    @Autowired
    IGuiguPickUserDetailsService guiguPickUserDetailsService;


    @Autowired
    GuiguPasswordEncoder guiguPasswordEncoder;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        GuiguMobileCodeAuthenticationToken authenticationToken= (GuiguMobileCodeAuthenticationToken) authentication;

        String code = authenticationToken.getCode();

        GuiguPickUser guiguPickUser = authenticationToken.getGuiguPickUser();

        GuiguPickUser userDetails = guiguPickUserDetailsService.loadUser(guiguPickUser);


        String mobileCode = guiguPickStringCacheManager.getString(String.format(RedisKeyConstant.LOGIN_MOBILE_CODE_KEY,guiguPickUser.getPhone()));
        if(!StringUtils.hasText(mobileCode)){
            log.debug("mobileCode is not exists in redis server : {}",guiguPickUser.getPhone());
            throw new BadCredentialsException("验证码已失效");
        }

        if(!mobileCode.equals(code)){
            log.debug("mobileCode is not correct in redis server :email is {} code is {}",guiguPickUser.getPhone(),code);
            throw new BadCredentialsException("验证码不正确");
        }
        userDetails.setLoginType(guiguPickUser.getLoginType());
        userDetails.setPassword("*************");
        return GuiguUsernamePasswordAuthenticationToken.authenticated(userDetails,userDetails.getAuthorities());
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return GuiguMobileCodeAuthenticationToken.class.isAssignableFrom(authentication);
    }
}
